
#ifndef _MEMBER_BSOURCE_H_
#define _MEMBER_BSOURCE_H_

#include <BMap>
#include <BEnum>
#include <BScript>
#include <BSource>
#include "IStack.h"
#include "ILibrary.h"

#define source_member(source)	((member_BSource*)((BSource*)source)->_ptr)

namespace BWE
{
	typedef BString::const_iterator	StrCit;

	class member_BSource
	{
	public:
		member_BSource(BSource* source);
		~member_BSource();

		BString& errorMessage(BExp* exp = 0);
		void raiseMessage(Signal signal);

		bool isType(BString& text);
		bool isName(const BString& text);

		StrCit nextWord(BString& word, const BString& text, StrCit& cit, int& line);

		BExp* create(Syntax syntax);
		BExp* create(Syntax syntax, int line, int begin, int end);

		BExp* parse(const BString& text, StrCit& cit, int& line);
		BExp* analyse(BExpHolderArray& exps);
		BExp* createSyntax(const BString& word);
		BExp* createAccess(BString& word);
		BExp* createValue(BString& word);
		BExp* createOpera(BString& word);
		BExp* createMacro(const BString& text, StrCit& cit, int& line);
		BExp* createLineNote(const BString& text, StrCit& cit, int& line);
		BExp* createBlockNote(const BString& text, StrCit& cit, int& line);
		bool collateParams(BExpHolderArray& exps);
		bool includeText(BExp* include, const BString& text);
		ILibrary* includeLibrary(const BString& libname);
		void organizeLevel(BExp* exp);

		bool checkExp(BExp* exp);
		bool checkArray(BExp* exp);
		bool checkAssign(BExp* exp);
		bool checkNew(BExp* exp);
		bool checkDecl(BExp* exp);
		bool checkName(BExp* exp);
		bool checkSelf(BExp* exp);
		bool checkOpera(BExp* exp);
		bool checkCall(BExp* exp);
		bool checkTest(BExp* exp);
		bool checkAndOr(BExp* exp);
		bool checkIf(BExp* exp);
		bool checkElse(BExp* exp);
		bool checkWhile(BExp* exp);
		bool checkFor(BExp* exp);
		bool checkSwitch(BExp* exp);
		bool checkCase(BExp* exp);
		bool checkBreak(BExp* exp);
		bool checkDefault(BExp* exp);
		bool checkContinue(BExp* exp);
		bool checkReturn(BExp* exp);
		bool checkEnum(BExp* exp);
		bool checkClass(BExp* exp);
		bool checkMethod(BExp* exp);
		bool checkFunction(BExp* exp);
		bool checkSubs(BExp* exp);

		BString checkFormula(BExpHolderArray& exps);
		VariantInfo* findVariant(const BString& name);
		VariantInfo* findVariant(BExpHolderArray& exps);

		int findSplit(BExpHolderArray& exps);
		bool invertValue(BExp* exp);

		BClass* createTempClass(BExp* exp);

		BClass* findSelf();
		BClass* findClass(const BString& type);
		BEnum* findEnum(const BString& type);
		bool checkType(BClass* cls, const BString& type);

		BString funcName(BExp* exp);
		FuncInfo* findFunction(BExp* exp);
		MethodInfo* findMethod(BExp* exp, BClass* cls);
		MethodInfo* findConvertMethod(const BString& type, ParamInfo& pinfo);
		bool matchMethod(const ParamInfoArray& pinfos, MethodInfo* minfo);
		bool matchFunction(const ParamInfoArray& pinfos, FuncInfo* finfo);
		bool applyOpera(BExp* exp);

		BSource*				boss;
		BScript*				script;
		BString					fileName;
		BString					text;

		BMap<BString, BString>	cachedFileMap;
		bool					error;
		BValue					message;
		BArray<int>				levels;
		IStack<VariantInfo>		stack;
		BStringArray			srcnames;
		BArray<BExpHolder>		document;
		BArray<BExpHolder>		includes;
		BArray<BExpHolder>		declares;
		BArray<BString>			tempTypes;

		BMap<BString, BClassHolder>		structMap;
		BMap<BString, BClassHolder>		classMap;
		BMap<BString, BEnumHolder>		enumMap;
		BMap<BString, FuncInfoHolder>	functionMap;

	};
}

#endif